Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Adds an init workflow to generate MCP configuration files for supported coding agents, and updates the landing site/docs to reflect the new setup flow and refreshed UI/layout behavior.
Changes:
- Add
contextplus init <agent>CLI subcommand to write agent-specific MCP config files. - Update landing setup UI/content to show runner-specific JSON config and a copyable init command.
- Misc landing refactors/tweaks (layout breakpoints, OpenNext Cloudflare dev init, config formatting).
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/index.ts |
Adds init subcommand, runner/agent parsing, and MCP config file generation. |
landing/wrangler.jsonc |
Reformat Wrangler config (structure unchanged). |
landing/src/components/LetterGlitch.tsx |
Adjusts hook dependencies for animation lifecycle. |
landing/src/components/IsometricDiagram.tsx |
Tweaks responsive thresholds and spacing logic. |
landing/src/components/InstructionsSection.tsx |
Updates displayed “2-line header” example and removes a JSX comment. |
landing/src/components/IdeSetup.tsx |
Adds runner-specific args and a copyable terminal init command block. |
landing/src/components/Background.tsx |
Removes a JSX comment. |
landing/src/app/page.tsx |
Refactors tool group rendering + tool reference rows into data-driven maps. |
landing/src/app/globals.css |
Adjusts responsive min-heights and adds intermediate breakpoint rules. |
landing/open-next.config.ts |
Simplifies OpenNext Cloudflare config to an empty config object. |
landing/next.config.ts |
Initializes OpenNext Cloudflare dev integration during Next config load. |
README.md |
Documents the new init command and updates config variable descriptions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Every file MUST start with exactly 2 comment lines (10 words each) explaining the file: | ||
|
|
||
| \`\`\` | ||
| // Regex-based symbol extraction engine for multi-language AST parsing | ||
| // FEATURE: Core parsing layer for structural code analysis | ||
| Regex-based symbol extraction engine for multi-language AST parsing | ||
| FEATURE: Core parsing layer for structural code analysis | ||
| \`\`\` |
There was a problem hiding this comment.
The example under “Every file MUST start with exactly 2 comment lines …” no longer includes the // comment prefix, but the surrounding text explicitly says these must be comment lines. This makes the instructions internally inconsistent; the example should include // on both lines (or the rule text should be updated to match the example).
| @@ -16,7 +17,79 @@ import { listRestorePoints, restorePoint } from "./git/shadow.js"; | |||
| import { semanticNavigate } from "./tools/semantic-navigate.js"; | |||
| import { getFeatureHub } from "./tools/feature-hub.js"; | |||
|
|
|||
| const ROOT_DIR = process.argv[2] ? resolve(process.argv[2]) : process.cwd(); | |||
| type AgentTarget = "claude" | "cursor" | "vscode" | "windsurf"; | |||
|
|
|||
| const AGENT_CONFIG_PATH: Record<AgentTarget, string> = { | |||
| claude: ".mcp.json", | |||
| cursor: ".cursor/mcp.json", | |||
| vscode: ".vscode/mcp.json", | |||
| windsurf: ".windsurf/mcp.json", | |||
| }; | |||
|
|
|||
| const passthroughArgs = process.argv.slice(2); | |||
| const ROOT_DIR = passthroughArgs[0] && passthroughArgs[0] !== "init" | |||
| ? resolve(passthroughArgs[0]) | |||
| : process.cwd(); | |||
|
|
|||
| function parseAgentTarget(input?: string): AgentTarget { | |||
| const normalized = (input ?? "claude").toLowerCase(); | |||
| if (normalized === "claude" || normalized === "claude-code") return "claude"; | |||
| if (normalized === "cursor") return "cursor"; | |||
| if (normalized === "vscode" || normalized === "vs-code" || normalized === "vs") return "vscode"; | |||
| if (normalized === "windsurf") return "windsurf"; | |||
| throw new Error(`Unsupported coding agent \"${input}\". Use one of: claude, cursor, vscode, windsurf.`); | |||
| } | |||
|
|
|||
| function parseRunner(args: string[]): "npx" | "bunx" { | |||
| const explicit = args.find((arg) => arg.startsWith("--runner=")); | |||
| if (explicit) { | |||
| const value = explicit.split("=")[1]; | |||
| if (value === "npx" || value === "bunx") return value; | |||
| throw new Error(`Unsupported runner \"${value}\". Use --runner=npx or --runner=bunx.`); | |||
| } | |||
| const runnerFlagIndex = args.findIndex((arg) => arg === "--runner"); | |||
| if (runnerFlagIndex >= 0) { | |||
| const value = args[runnerFlagIndex + 1]; | |||
| if (value === "npx" || value === "bunx") return value; | |||
| throw new Error(`Unsupported runner \"${value}\". Use --runner=npx or --runner=bunx.`); | |||
| } | |||
| const userAgent = (process.env.npm_config_user_agent ?? "").toLowerCase(); | |||
| const execPath = (process.env.npm_execpath ?? "").toLowerCase(); | |||
| if (userAgent.includes("bun/") || execPath.includes("bun")) return "bunx"; | |||
| return "npx"; | |||
| } | |||
|
|
|||
| function buildMcpConfig(runner: "npx" | "bunx") { | |||
| const commandArgs = runner === "npx" ? ["-y", "contextplus"] : ["contextplus"]; | |||
| return JSON.stringify( | |||
| { | |||
| mcpServers: { | |||
| contextplus: { | |||
| command: runner, | |||
| args: commandArgs, | |||
| env: { | |||
| OLLAMA_EMBED_MODEL: "nomic-embed-text", | |||
| OLLAMA_CHAT_MODEL: "gemma2:27b", | |||
| OLLAMA_API_KEY: "YOUR_OLLAMA_API_KEY", | |||
| }, | |||
| }, | |||
| }, | |||
| }, | |||
| null, | |||
| 2, | |||
| ); | |||
| } | |||
|
|
|||
| async function runInitCommand(args: string[]) { | |||
| const nonFlags = args.filter((arg) => !arg.startsWith("--")); | |||
| const target = parseAgentTarget(nonFlags[0]); | |||
| const runner = parseRunner(args); | |||
| const outputPath = resolve(process.cwd(), AGENT_CONFIG_PATH[target]); | |||
| await mkdir(dirname(outputPath), { recursive: true }); | |||
| await writeFile(outputPath, `${buildMcpConfig(runner)}\n`, "utf8"); | |||
| console.error(`Context+ initialized for ${target} using ${runner}.`); | |||
| console.error(`Wrote MCP config: ${outputPath}`); | |||
| } | |||
There was a problem hiding this comment.
The new init subcommand is implemented in src/index.ts, but this entrypoint still imports and registers all MCP tools at module load time. That means running contextplus init ... will also load heavy dependencies (e.g., tree-sitter / semantic tooling) even though it only needs to write a small config file. Consider moving init into a separate lightweight CLI entry (or using a very early argument check + dynamic import) so init stays fast and doesn’t require the full runtime/toolchain to be available.
| const passthroughArgs = process.argv.slice(2); | ||
| const ROOT_DIR = passthroughArgs[0] && passthroughArgs[0] !== "init" | ||
| ? resolve(passthroughArgs[0]) | ||
| : process.cwd(); |
There was a problem hiding this comment.
ROOT_DIR now treats a first positional argument equal to "init" as the init subcommand and falls back to process.cwd(). This makes it impossible to analyze a project whose path is literally init (previously node build/index.js init would analyze ./init). Consider disambiguating subcommands from paths (e.g., require init to be the first arg and followed by a known agent/flag, or only treat it as a subcommand when there is no existing directory at that path).
| }; | ||
| // eslint-disable-next-line react-hooks/exhaustive-deps | ||
| }, [glitchSpeed, smooth]); | ||
| }, [animate, resizeCanvas]); |
There was a problem hiding this comment.
The useEffect dependency array now includes animate and resizeCanvas, but both functions are declared inline in the component and will be re-created on every render. This will cause the effect to teardown/re-init on every render (restarting the animation loop and re-binding the resize listener), which is both a performance issue and can lead to flicker. Consider stabilizing these functions (e.g., via useCallback + proper deps / refs) or moving their definitions inside the effect and depending on the actual props they use (e.g., glitchSpeed, smooth, etc.).
docs: fix incorrect pmll-memory-mcp relationship in Memory & RAG section
No description provided.